<?xml version='1.0' encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <link href="cpip.css" rel="stylesheet" type="text/css" />
    <title>File: /Users/paulross/dev/linux/linux-3.13/include/linux/srcu.h</title>
  </head>
  <body>
    <h1>File: /Users/paulross/dev/linux/linux-3.13/include/linux/srcu.h</h1>
    <p>Green shading in the line number column
means the source is part of the translation unit, red means it is conditionally excluded.
Highlighted line numbers link to the translation unit page. Highlighted macros link to
the macro page.</p>
    <pre><a name="1" /><span class="True">       1:</span> <span class="k">/*</span>
<a name="2" /><span class="True">       2:</span> <span class="k"> * Sleepable Read-Copy Update mechanism for mutual exclusion</span>
<a name="3" /><span class="True">       3:</span> <span class="k"> *</span>
<a name="4" /><span class="True">       4:</span> <span class="k"> * This program is free software; you can redistribute it and/or modify</span>
<a name="5" /><span class="True">       5:</span> <span class="k"> * it under the terms of the GNU General Public License as published by</span>
<a name="6" /><span class="True">       6:</span> <span class="k"> * the Free Software Foundation; either version 2 of the License, or</span>
<a name="7" /><span class="True">       7:</span> <span class="k"> * (at your option) any later version.</span>
<a name="8" /><span class="True">       8:</span> <span class="k"> *</span>
<a name="9" /><span class="True">       9:</span> <span class="k"> * This program is distributed in the hope that it will be useful,</span>
<a name="10" /><span class="True">      10:</span> <span class="k"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<a name="11" /><span class="True">      11:</span> <span class="k"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<a name="12" /><span class="True">      12:</span> <span class="k"> * GNU General Public License for more details.</span>
<a name="13" /><span class="True">      13:</span> <span class="k"> *</span>
<a name="14" /><span class="True">      14:</span> <span class="k"> * You should have received a copy of the GNU General Public License</span>
<a name="15" /><span class="True">      15:</span> <span class="k"> * along with this program; if not, write to the Free Software</span>
<a name="16" /><span class="True">      16:</span> <span class="k"> * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.</span>
<a name="17" /><span class="True">      17:</span> <span class="k"> *</span>
<a name="18" /><span class="True">      18:</span> <span class="k"> * Copyright (C) IBM Corporation, 2006</span>
<a name="19" /><span class="True">      19:</span> <span class="k"> * Copyright (C) Fujitsu, 2012</span>
<a name="20" /><span class="True">      20:</span> <span class="k"> *</span>
<a name="21" /><span class="True">      21:</span> <span class="k"> * Author: Paul McKenney &lt;paulmck@us.ibm.com&gt;</span>
<a name="22" /><span class="True">      22:</span> <span class="k"> *       Lai Jiangshan &lt;laijs@cn.fujitsu.com&gt;</span>
<a name="23" /><span class="True">      23:</span> <span class="k"> *</span>
<a name="24" /><span class="True">      24:</span> <span class="k"> * For detailed explanation of Read-Copy Update mechanism see -</span>
<a name="25" /><span class="True">      25:</span> <span class="k"> *         Documentation/RCU/ *.txt</span>
<a name="26" /><span class="True">      26:</span> <span class="k"> *</span>
<a name="27" /><span class="True">      27:</span> <span class="k"> */</span>
<a name="28" /><span class="True">      28:</span> 
<a name="29" /><span class="True">      29:</span> <span class="f">#</span><span class="n">ifndef</span> <a href="cpu.c_macros_noref.html#_X0xJTlVYX1NSQ1VfSF8w"><span class="b">_LINUX_SRCU_H</span></a>
<a name="30" /><span class="True">      30:</span> <span class="f">#</span><span class="n">define</span> <a href="cpu.c_macros_noref.html#_X0xJTlVYX1NSQ1VfSF8w"><span class="b">_LINUX_SRCU_H</span></a>
<a name="31" /><span class="True">      31:</span> 
<a name="32" /><span class="True">      32:</span> <span class="f">#</span><span class="n">include</span> <span class="f">&lt;</span><span class="b">linux</span><span class="f">/</span><span class="b">mutex</span><span class="f">.</span><span class="b">h</span><span class="f">&gt;</span>
<a name="33" /><span class="True">      33:</span> <span class="f">#</span><span class="n">include</span> <span class="f">&lt;</span><span class="b">linux</span><span class="f">/</span><span class="b">rcupdate</span><span class="f">.</span><span class="b">h</span><span class="f">&gt;</span>
<a name="34" /><span class="True">      34:</span> <span class="f">#</span><span class="n">include</span> <span class="f">&lt;</span><span class="b">linux</span><span class="f">/</span><span class="b">workqueue</span><span class="f">.</span><span class="b">h</span><span class="f">&gt;</span>
<a name="35" /><span class="True">      35:</span> 
<a name="36" /><span class="True">      36:</span> <span class="m">struct</span> <span class="b">srcu_struct_array</span> <span class="f">{</span>
<a name="37" /><span class="True">      37:</span>     <span class="m">unsigned</span> <span class="m">long</span> <span class="b">c</span><span class="f">[</span><span class="c">2</span><span class="f">]</span><span class="f">;</span>
<a name="38" /><span class="True">      38:</span>     <span class="m">unsigned</span> <span class="m">long</span> <span class="b">seq</span><span class="f">[</span><span class="c">2</span><span class="f">]</span><span class="f">;</span>
<a name="39" /><span class="True">      39:</span> <span class="f">}</span><span class="f">;</span>
<a name="40" /><span class="True">      40:</span> 
<a name="41" /><span class="True">      41:</span> <span class="m">struct</span> <span class="b">rcu_batch</span> <span class="f">{</span>
<a name="42" /><span class="True">      42:</span>     <span class="m">struct</span> <a href="cpu.c_macros_ref.html#_cmN1X2hlYWRfMA__"><span class="b">rcu_head</span></a> <span class="f">*</span><span class="b">head</span><span class="f">,</span> <span class="f">*</span><span class="f">*</span><span class="b">tail</span><span class="f">;</span>
<a name="43" /><span class="True">      43:</span> <span class="f">}</span><span class="f">;</span>
<a name="44" /><span class="True">      44:</span> 
<a name="45" /><span class="True">      45:</span> <span class="f">#</span><span class="n">define</span> <a href="cpu.c_macros_noref.html#_UkNVX0JBVENIX0lOSVRfMA__"><span class="b">RCU_BATCH_INIT</span></a><span class="f">(</span><span class="b">name</span><span class="f">)</span> <span class="f">{</span> <a href="cpu.c_macros_ref.html#_TlVMTF8w"><span class="b">NULL</span></a><span class="f">,</span> <span class="f">&amp;</span><span class="f">(</span><span class="b">name</span><span class="f">.</span><span class="b">head</span><span class="f">)</span> <span class="f">}</span>
<a name="46" /><span class="True">      46:</span> 
<a name="47" /><span class="True">      47:</span> <span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">{</span>
<a name="48" /><span class="True">      48:</span>     <span class="m">unsigned</span> <span class="b">completed</span><span class="f">;</span>
<a name="49" /><span class="True">      49:</span>     <span class="m">struct</span> <span class="b">srcu_struct_array</span> <a href="cpu.c_macros_ref.html#_X19wZXJjcHVfMA__"><span class="b">__percpu</span></a> <span class="f">*</span><span class="b">per_cpu_ref</span><span class="f">;</span>
<a name="50" /><span class="True">      50:</span>     <span class="b">spinlock_t</span> <span class="b">queue_lock</span><span class="f">;</span> <span class="k">/* protect -&gt;batch_queue, -&gt;running */</span>
<a name="51" /><span class="True">      51:</span>     <span class="m">bool</span> <span class="b">running</span><span class="f">;</span>
<a name="52" /><span class="True">      52:</span>     <span class="k">/* callbacks just queued */</span>
<a name="53" /><span class="True">      53:</span>     <span class="m">struct</span> <span class="b">rcu_batch</span> <span class="b">batch_queue</span><span class="f">;</span>
<a name="54" /><span class="True">      54:</span>     <span class="k">/* callbacks try to do the first check_zero */</span>
<a name="55" /><span class="True">      55:</span>     <span class="m">struct</span> <span class="b">rcu_batch</span> <span class="b">batch_check0</span><span class="f">;</span>
<a name="56" /><span class="True">      56:</span>     <span class="k">/* callbacks done with the first check_zero and the flip */</span>
<a name="57" /><span class="True">      57:</span>     <span class="m">struct</span> <span class="b">rcu_batch</span> <span class="b">batch_check1</span><span class="f">;</span>
<a name="58" /><span class="True">      58:</span>     <span class="m">struct</span> <span class="b">rcu_batch</span> <span class="b">batch_done</span><span class="f">;</span>
<a name="59" /><span class="True">      59:</span>     <span class="m">struct</span> <span class="b">delayed_work</span> <span class="b">work</span><span class="f">;</span>
<a name="60" /><span class="False">      60:</span> <span class="f">#</span><span class="n">ifdef</span> <span class="b">CONFIG_DEBUG_LOCK_ALLOC</span>
<a name="61" /><span class="False">      61:</span>     <span class="m">struct</span> <span class="b">lockdep_map</span> <span class="b">dep_map</span><span class="f">;</span>
<a name="62" /><span class="True">      62:</span> <span class="f">#</span><span class="n">endif</span> <span class="k">/* #ifdef CONFIG_DEBUG_LOCK_ALLOC */</span>
<a name="63" /><span class="True">      63:</span> <span class="f">}</span><span class="f">;</span>
<a name="64" /><span class="True">      64:</span> 
<a name="65" /><span class="False">      65:</span> <span class="f">#</span><span class="n">ifdef</span> <span class="b">CONFIG_DEBUG_LOCK_ALLOC</span>
<a name="66" /><span class="False">      66:</span> 
<a name="67" /><span class="False">      67:</span> <span class="m">int</span> <span class="b">__init_srcu_struct</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">,</span> <span class="m">const</span> <span class="m">char</span> <span class="f">*</span><span class="b">name</span><span class="f">,</span>
<a name="68" /><span class="False">      68:</span>                <span class="m">struct</span> <span class="b">lock_class_key</span> <span class="f">*</span><span class="b">key</span><span class="f">)</span><span class="f">;</span>
<a name="69" /><span class="False">      69:</span> 
<a name="70" /><span class="False">      70:</span> <span class="f">#</span><span class="n">define</span> <span class="b">init_srcu_struct</span><span class="f">(</span><span class="b">sp</span><span class="f">)</span> \
<a name="71" /><span class="False">      71:</span> <span class="f">(</span><span class="f">{</span> \
<a name="72" /><span class="False">      72:</span>     <span class="m">static</span> <span class="m">struct</span> <span class="b">lock_class_key</span> <span class="b">__srcu_key</span><span class="f">;</span> \
<a name="73" /><span class="False">      73:</span>     \
<a name="74" /><span class="False">      74:</span>     <span class="b">__init_srcu_struct</span><span class="f">(</span><span class="f">(</span><span class="b">sp</span><span class="f">)</span><span class="f">,</span> <span class="f">#</span><span class="b">sp</span><span class="f">,</span> <span class="f">&amp;</span><span class="b">__srcu_key</span><span class="f">)</span><span class="f">;</span> \
<a name="75" /><span class="False">      75:</span> <span class="f">}</span><span class="f">)</span>
<a name="76" /><span class="False">      76:</span> 
<a name="77" /><span class="False">      77:</span> <span class="f">#</span><span class="n">define</span> <a href="cpu.c_macros_noref.html#_X19TUkNVX0RFUF9NQVBfSU5JVF8w"><span class="b">__SRCU_DEP_MAP_INIT</span></a><span class="f">(</span><span class="b">srcu_name</span><span class="f">)</span>    <span class="f">.</span><span class="b">dep_map</span> <span class="f">=</span> <span class="f">{</span> <span class="f">.</span><span class="b">name</span> <span class="f">=</span> <span class="f">#</span><span class="b">srcu_name</span> <span class="f">}</span><span class="f">,</span>
<a name="78" /><span class="True">      78:</span> <span class="f">#</span><span class="n">else</span> <span class="k">/* #ifdef CONFIG_DEBUG_LOCK_ALLOC */</span>
<a name="79" /><span class="True">      79:</span> 
<a name="80" /><span class="True">      80:</span> <span class="m">int</span> <span class="b">init_srcu_struct</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">)</span><span class="f">;</span>
<a name="81" /><span class="True">      81:</span> 
<a name="82" /><span class="True">      82:</span> <span class="f">#</span><span class="n">define</span> <a href="cpu.c_macros_noref.html#_X19TUkNVX0RFUF9NQVBfSU5JVF8w"><span class="b">__SRCU_DEP_MAP_INIT</span></a><span class="f">(</span><span class="b">srcu_name</span><span class="f">)</span>
<a name="83" /><span class="True">      83:</span> <span class="f">#</span><span class="n">endif</span> <span class="k">/* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */</span>
<a name="84" /><span class="True">      84:</span> 
<a name="85" /><span class="True">      85:</span> <span class="m">void</span> <span class="b">process_srcu</span><span class="f">(</span><span class="m">struct</span> <span class="b">work_struct</span> <span class="f">*</span><span class="b">work</span><span class="f">)</span><span class="f">;</span>
<a name="86" /><span class="True">      86:</span> 
<a name="87" /><span class="True">      87:</span> <span class="f">#</span><span class="n">define</span> <a href="cpu.c_macros_noref.html#_X19TUkNVX1NUUlVDVF9JTklUXzA_"><span class="b">__SRCU_STRUCT_INIT</span></a><span class="f">(</span><span class="b">name</span><span class="f">)</span>                    \
<a name="88" /><span class="True">      88:</span>     <span class="f">{</span>                                \
<a name="89" /><span class="True">      89:</span>         <span class="f">.</span><span class="b">completed</span> <span class="f">=</span> <span class="f">-</span><span class="c">300</span><span class="f">,</span>                    \
<a name="90" /><span class="True">      90:</span>         <span class="f">.</span><span class="b">per_cpu_ref</span> <span class="f">=</span> <span class="f">&amp;</span><span class="b">name</span><span class="f">##</span><span class="b">_srcu_array</span><span class="f">,</span>            \
<a name="91" /><span class="True">      91:</span>         <span class="f">.</span><span class="b">queue_lock</span> <span class="f">=</span> <a href="cpu.c_macros_ref.html#_X19TUElOX0xPQ0tfVU5MT0NLRURfMA__"><span class="b">__SPIN_LOCK_UNLOCKED</span></a><span class="f">(</span><span class="b">name</span><span class="f">.</span><span class="b">queue_lock</span><span class="f">)</span><span class="f">,</span>    \
<a name="92" /><span class="True">      92:</span>         <span class="f">.</span><span class="b">running</span> <span class="f">=</span> <span class="m">false</span><span class="f">,</span>                    \
<a name="93" /><span class="True">      93:</span>         <span class="f">.</span><span class="b">batch_queue</span> <span class="f">=</span> <a href="cpu.c_macros_noref.html#_UkNVX0JBVENIX0lOSVRfMA__"><span class="b">RCU_BATCH_INIT</span></a><span class="f">(</span><span class="b">name</span><span class="f">.</span><span class="b">batch_queue</span><span class="f">)</span><span class="f">,</span>    \
<a name="94" /><span class="True">      94:</span>         <span class="f">.</span><span class="b">batch_check0</span> <span class="f">=</span> <a href="cpu.c_macros_noref.html#_UkNVX0JBVENIX0lOSVRfMA__"><span class="b">RCU_BATCH_INIT</span></a><span class="f">(</span><span class="b">name</span><span class="f">.</span><span class="b">batch_check0</span><span class="f">)</span><span class="f">,</span>    \
<a name="95" /><span class="True">      95:</span>         <span class="f">.</span><span class="b">batch_check1</span> <span class="f">=</span> <a href="cpu.c_macros_noref.html#_UkNVX0JBVENIX0lOSVRfMA__"><span class="b">RCU_BATCH_INIT</span></a><span class="f">(</span><span class="b">name</span><span class="f">.</span><span class="b">batch_check1</span><span class="f">)</span><span class="f">,</span>    \
<a name="96" /><span class="True">      96:</span>         <span class="f">.</span><span class="b">batch_done</span> <span class="f">=</span> <a href="cpu.c_macros_noref.html#_UkNVX0JBVENIX0lOSVRfMA__"><span class="b">RCU_BATCH_INIT</span></a><span class="f">(</span><span class="b">name</span><span class="f">.</span><span class="b">batch_done</span><span class="f">)</span><span class="f">,</span>        \
<a name="97" /><span class="True">      97:</span>         <span class="f">.</span><span class="b">work</span> <span class="f">=</span> <a href="cpu.c_macros_noref.html#_X19ERUxBWUVEX1dPUktfSU5JVElBTElaRVJfMA__"><span class="b">__DELAYED_WORK_INITIALIZER</span></a><span class="f">(</span><span class="b">name</span><span class="f">.</span><span class="b">work</span><span class="f">,</span> <span class="b">process_srcu</span><span class="f">,</span> <span class="c">0</span><span class="f">)</span><span class="f">,\
</span>        <a href="cpu.c_macros_noref.html#_X19TUkNVX0RFUF9NQVBfSU5JVF8w"><span class="b">__SRCU_DEP_MAP_INIT</span></a><span class="f">(</span><span class="b">name</span><span class="f">)</span>                \
<a name="99" /><span class="True">      99:</span>     <span class="f">}</span>
<a name="100" /><span class="True">     100:</span> 
<a name="101" /><span class="True">     101:</span> <span class="k">/*</span>
<a name="102" /><span class="True">     102:</span> <span class="k"> * define and init a srcu struct at build time.</span>
<a name="103" /><span class="True">     103:</span> <span class="k"> * dont&apos;t call init_srcu_struct() nor cleanup_srcu_struct() on it.</span>
<a name="104" /><span class="True">     104:</span> <span class="k"> */</span>
<a name="105" /><span class="True">     105:</span> <span class="f">#</span><span class="n">define</span> <a href="cpu.c_macros_noref.html#_REVGSU5FX1NSQ1VfMA__"><span class="b">DEFINE_SRCU</span></a><span class="f">(</span><span class="b">name</span><span class="f">)</span>                        \
<a name="106" /><span class="True">     106:</span>     <span class="m">static</span> <a href="cpu.c_macros_noref.html#_REVGSU5FX1BFUl9DUFVfMA__"><span class="b">DEFINE_PER_CPU</span></a><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct_array</span><span class="f">,</span> <span class="b">name</span><span class="f">##</span><span class="b">_srcu_array</span><span class="f">)</span><span class="f">;\
</span>    <span class="m">struct</span> <span class="b">srcu_struct</span> <span class="b">name</span> <span class="f">=</span> <a href="cpu.c_macros_noref.html#_X19TUkNVX1NUUlVDVF9JTklUXzA_"><span class="b">__SRCU_STRUCT_INIT</span></a><span class="f">(</span><span class="b">name</span><span class="f">)</span><span class="f">;</span>
<a name="108" /><span class="True">     108:</span> 
<a name="109" /><span class="True">     109:</span> <span class="f">#</span><span class="n">define</span> <a href="cpu.c_macros_noref.html#_REVGSU5FX1NUQVRJQ19TUkNVXzA_"><span class="b">DEFINE_STATIC_SRCU</span></a><span class="f">(</span><span class="b">name</span><span class="f">)</span>                    \
<a name="110" /><span class="True">     110:</span>     <span class="m">static</span> <a href="cpu.c_macros_noref.html#_REVGSU5FX1BFUl9DUFVfMA__"><span class="b">DEFINE_PER_CPU</span></a><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct_array</span><span class="f">,</span> <span class="b">name</span><span class="f">##</span><span class="b">_srcu_array</span><span class="f">)</span><span class="f">;\
</span>    <span class="m">static</span> <span class="m">struct</span> <span class="b">srcu_struct</span> <span class="b">name</span> <span class="f">=</span> <a href="cpu.c_macros_noref.html#_X19TUkNVX1NUUlVDVF9JTklUXzA_"><span class="b">__SRCU_STRUCT_INIT</span></a><span class="f">(</span><span class="b">name</span><span class="f">)</span><span class="f">;</span>
<a name="112" /><span class="True">     112:</span> 
<a name="113" /><span class="True">     113:</span> <span class="k">/**</span>
<a name="114" /><span class="True">     114:</span> <span class="k"> * call_srcu() - Queue a callback for invocation after an SRCU grace period</span>
<a name="115" /><span class="True">     115:</span> <span class="k"> * @sp: srcu_struct in queue the callback</span>
<a name="116" /><span class="True">     116:</span> <span class="k"> * @head: structure to be used for queueing the SRCU callback.</span>
<a name="117" /><span class="True">     117:</span> <span class="k"> * @func: function to be invoked after the SRCU grace period</span>
<a name="118" /><span class="True">     118:</span> <span class="k"> *</span>
<a name="119" /><span class="True">     119:</span> <span class="k"> * The callback function will be invoked some time after a full SRCU</span>
<a name="120" /><span class="True">     120:</span> <span class="k"> * grace period elapses, in other words after all pre-existing SRCU</span>
<a name="121" /><span class="True">     121:</span> <span class="k"> * read-side critical sections have completed.  However, the callback</span>
<a name="122" /><span class="True">     122:</span> <span class="k"> * function might well execute concurrently with other SRCU read-side</span>
<a name="123" /><span class="True">     123:</span> <span class="k"> * critical sections that started after call_srcu() was invoked.  SRCU</span>
<a name="124" /><span class="True">     124:</span> <span class="k"> * read-side critical sections are delimited by srcu_read_lock() and</span>
<a name="125" /><span class="True">     125:</span> <span class="k"> * srcu_read_unlock(), and may be nested.</span>
<a name="126" /><span class="True">     126:</span> <span class="k"> *</span>
<a name="127" /><span class="True">     127:</span> <span class="k"> * The callback will be invoked from process context, but must nevertheless</span>
<a name="128" /><span class="True">     128:</span> <span class="k"> * be fast and must not block.</span>
<a name="129" /><span class="True">     129:</span> <span class="k"> */</span>
<a name="130" /><span class="True">     130:</span> <span class="m">void</span> <span class="b">call_srcu</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">,</span> <span class="m">struct</span> <a href="cpu.c_macros_ref.html#_cmN1X2hlYWRfMA__"><span class="b">rcu_head</span></a> <span class="f">*</span><span class="b">head</span><span class="f">,</span>
<a name="131" /><span class="True">     131:</span>         <span class="m">void</span> <span class="f">(</span><span class="f">*</span><span class="b">func</span><span class="f">)</span><span class="f">(</span><span class="m">struct</span> <a href="cpu.c_macros_ref.html#_cmN1X2hlYWRfMA__"><span class="b">rcu_head</span></a> <span class="f">*</span><span class="b">head</span><span class="f">)</span><span class="f">)</span><span class="f">;</span>
<a name="132" /><span class="True">     132:</span> 
<a name="133" /><span class="True">     133:</span> <span class="m">void</span> <span class="b">cleanup_srcu_struct</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">)</span><span class="f">;</span>
<a name="134" /><span class="True">     134:</span> <span class="m">int</span> <span class="b">__srcu_read_lock</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">)</span> <a href="cpu.c_macros_ref.html#_X19hY3F1aXJlc18w"><span class="b">__acquires</span></a><span class="f">(</span><span class="b">sp</span><span class="f">)</span><span class="f">;</span>
<a name="135" /><span class="True">     135:</span> <span class="m">void</span> <span class="b">__srcu_read_unlock</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">,</span> <span class="m">int</span> <span class="b">idx</span><span class="f">)</span> <a href="cpu.c_macros_ref.html#_X19yZWxlYXNlc18w"><span class="b">__releases</span></a><span class="f">(</span><span class="b">sp</span><span class="f">)</span><span class="f">;</span>
<a name="136" /><span class="True">     136:</span> <span class="m">void</span> <span class="b">synchronize_srcu</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">)</span><span class="f">;</span>
<a name="137" /><span class="True">     137:</span> <span class="m">void</span> <span class="b">synchronize_srcu_expedited</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">)</span><span class="f">;</span>
<a name="138" /><span class="True">     138:</span> <span class="m">long</span> <span class="b">srcu_batches_completed</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">)</span><span class="f">;</span>
<a name="139" /><span class="True">     139:</span> <span class="m">void</span> <span class="b">srcu_barrier</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">)</span><span class="f">;</span>
<a name="140" /><span class="True">     140:</span> 
<a name="141" /><span class="False">     141:</span> <span class="f">#</span><span class="n">ifdef</span> <span class="b">CONFIG_DEBUG_LOCK_ALLOC</span>
<a name="142" /><span class="False">     142:</span> 
<a name="143" /><span class="False">     143:</span> <span class="k">/**</span>
<a name="144" /><span class="False">     144:</span> <span class="k"> * srcu_read_lock_held - might we be in SRCU read-side critical section?</span>
<a name="145" /><span class="False">     145:</span> <span class="k"> *</span>
<a name="146" /><span class="False">     146:</span> <span class="k"> * If CONFIG_DEBUG_LOCK_ALLOC is selected, returns nonzero iff in an SRCU</span>
<a name="147" /><span class="False">     147:</span> <span class="k"> * read-side critical section.  In absence of CONFIG_DEBUG_LOCK_ALLOC,</span>
<a name="148" /><span class="False">     148:</span> <span class="k"> * this assumes we are in an SRCU read-side critical section unless it can</span>
<a name="149" /><span class="False">     149:</span> <span class="k"> * prove otherwise.</span>
<a name="150" /><span class="False">     150:</span> <span class="k"> *</span>
<a name="151" /><span class="False">     151:</span> <span class="k"> * Checks debug_lockdep_rcu_enabled() to prevent false positives during boot</span>
<a name="152" /><span class="False">     152:</span> <span class="k"> * and while lockdep is disabled.</span>
<a name="153" /><span class="False">     153:</span> <span class="k"> *</span>
<a name="154" /><span class="False">     154:</span> <span class="k"> * Note that SRCU is based on its own statemachine and it doesn&apos;t</span>
<a name="155" /><span class="False">     155:</span> <span class="k"> * relies on normal RCU, it can be called from the CPU which</span>
<a name="156" /><span class="False">     156:</span> <span class="k"> * is in the idle loop from an RCU point of view or offline.</span>
<a name="157" /><span class="False">     157:</span> <span class="k"> */</span>
<a name="158" /><span class="False">     158:</span> <span class="m">static</span> <span class="m">inline</span> <span class="m">int</span> <span class="b">srcu_read_lock_held</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">)</span>
<a name="159" /><span class="False">     159:</span> <span class="f">{</span>
<a name="160" /><span class="False">     160:</span>     <span class="m">if</span> <span class="f">(</span><span class="f">!</span><span class="b">debug_lockdep_rcu_enabled</span><span class="f">(</span><span class="f">)</span><span class="f">)</span>
<a name="161" /><span class="False">     161:</span>         <span class="m">return</span> <span class="c">1</span><span class="f">;</span>
<a name="162" /><span class="False">     162:</span>     <span class="m">return</span> <span class="b">lock_is_held</span><span class="f">(</span><span class="f">&amp;</span><span class="b">sp</span><span class="f">-&gt;</span><span class="b">dep_map</span><span class="f">)</span><span class="f">;</span>
<a name="163" /><span class="False">     163:</span> <span class="f">}</span>
<a name="164" /><span class="False">     164:</span> 
<a name="165" /><span class="True">     165:</span> <span class="f">#</span><span class="n">else</span> <span class="k">/* #ifdef CONFIG_DEBUG_LOCK_ALLOC */</span>
<a name="166" /><span class="True">     166:</span> 
<a name="167" /><span class="True">     167:</span> <span class="m">static</span> <span class="m">inline</span> <span class="m">int</span> <span class="b">srcu_read_lock_held</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">)</span>
<a name="168" /><span class="True">     168:</span> <span class="f">{</span>
<a name="169" /><span class="True">     169:</span>     <span class="m">return</span> <span class="c">1</span><span class="f">;</span>
<a name="170" /><span class="True">     170:</span> <span class="f">}</span>
<a name="171" /><span class="True">     171:</span> 
<a name="172" /><span class="True">     172:</span> <span class="f">#</span><span class="n">endif</span> <span class="k">/* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */</span>
<a name="173" /><span class="True">     173:</span> 
<a name="174" /><span class="True">     174:</span> <span class="k">/**</span>
<a name="175" /><span class="True">     175:</span> <span class="k"> * srcu_dereference_check - fetch SRCU-protected pointer for later dereferencing</span>
<a name="176" /><span class="True">     176:</span> <span class="k"> * @p: the pointer to fetch and protect for later dereferencing</span>
<a name="177" /><span class="True">     177:</span> <span class="k"> * @sp: pointer to the srcu_struct, which is used to check that we</span>
<a name="178" /><span class="True">     178:</span> <span class="k"> *    really are in an SRCU read-side critical section.</span>
<a name="179" /><span class="True">     179:</span> <span class="k"> * @c: condition to check for update-side use</span>
<a name="180" /><span class="True">     180:</span> <span class="k"> *</span>
<a name="181" /><span class="True">     181:</span> <span class="k"> * If PROVE_RCU is enabled, invoking this outside of an RCU read-side</span>
<a name="182" /><span class="True">     182:</span> <span class="k"> * critical section will result in an RCU-lockdep splat, unless @c evaluates</span>
<a name="183" /><span class="True">     183:</span> <span class="k"> * to 1.  The @c argument will normally be a logical expression containing</span>
<a name="184" /><span class="True">     184:</span> <span class="k"> * lockdep_is_held() calls.</span>
<a name="185" /><span class="True">     185:</span> <span class="k"> */</span>
<a name="186" /><span class="True">     186:</span> <span class="f">#</span><span class="n">define</span> <a href="cpu.c_macros_noref.html#_c3JjdV9kZXJlZmVyZW5jZV9jaGVja18w"><span class="b">srcu_dereference_check</span></a><span class="f">(</span><span class="b">p</span><span class="f">,</span> <span class="b">sp</span><span class="f">,</span> <span class="b">c</span><span class="f">)</span> \
<a name="187" /><span class="True">     187:</span>     <a href="cpu.c_macros_ref.html#_X19yY3VfZGVyZWZlcmVuY2VfY2hlY2tfMA__"><span class="b">__rcu_dereference_check</span></a><span class="f">(</span><span class="f">(</span><span class="b">p</span><span class="f">)</span><span class="f">,</span> <span class="b">srcu_read_lock_held</span><span class="f">(</span><span class="b">sp</span><span class="f">)</span> <span class="f">||</span> <span class="f">(</span><span class="b">c</span><span class="f">)</span><span class="f">,</span> <a href="cpu.c_macros_ref.html#_X19yY3VfMA__"><span class="b">__rcu</span></a><span class="f">)</span>
<a name="188" /><span class="True">     188:</span> 
<a name="189" /><span class="True">     189:</span> <span class="k">/**</span>
<a name="190" /><span class="True">     190:</span> <span class="k"> * srcu_dereference - fetch SRCU-protected pointer for later dereferencing</span>
<a name="191" /><span class="True">     191:</span> <span class="k"> * @p: the pointer to fetch and protect for later dereferencing</span>
<a name="192" /><span class="True">     192:</span> <span class="k"> * @sp: pointer to the srcu_struct, which is used to check that we</span>
<a name="193" /><span class="True">     193:</span> <span class="k"> *    really are in an SRCU read-side critical section.</span>
<a name="194" /><span class="True">     194:</span> <span class="k"> *</span>
<a name="195" /><span class="True">     195:</span> <span class="k"> * Makes rcu_dereference_check() do the dirty work.  If PROVE_RCU</span>
<a name="196" /><span class="True">     196:</span> <span class="k"> * is enabled, invoking this outside of an RCU read-side critical</span>
<a name="197" /><span class="True">     197:</span> <span class="k"> * section will result in an RCU-lockdep splat.</span>
<a name="198" /><span class="True">     198:</span> <span class="k"> */</span>
<a name="199" /><span class="True">     199:</span> <span class="f">#</span><span class="n">define</span> <a href="cpu.c_macros_noref.html#_c3JjdV9kZXJlZmVyZW5jZV8w"><span class="b">srcu_dereference</span></a><span class="f">(</span><span class="b">p</span><span class="f">,</span> <span class="b">sp</span><span class="f">)</span> <a href="cpu.c_macros_noref.html#_c3JjdV9kZXJlZmVyZW5jZV9jaGVja18w"><span class="b">srcu_dereference_check</span></a><span class="f">(</span><span class="f">(</span><span class="b">p</span><span class="f">)</span><span class="f">,</span> <span class="f">(</span><span class="b">sp</span><span class="f">)</span><span class="f">,</span> <span class="c">0</span><span class="f">)</span>
<a name="200" /><span class="True">     200:</span> 
<a name="201" /><span class="True">     201:</span> <span class="k">/**</span>
<a name="202" /><span class="True">     202:</span> <span class="k"> * srcu_read_lock - register a new reader for an SRCU-protected structure.</span>
<a name="203" /><span class="True">     203:</span> <span class="k"> * @sp: srcu_struct in which to register the new reader.</span>
<a name="204" /><span class="True">     204:</span> <span class="k"> *</span>
<a name="205" /><span class="True">     205:</span> <span class="k"> * Enter an SRCU read-side critical section.  Note that SRCU read-side</span>
<a name="206" /><span class="True">     206:</span> <span class="k"> * critical sections may be nested.  However, it is illegal to</span>
<a name="207" /><span class="True">     207:</span> <span class="k"> * call anything that waits on an SRCU grace period for the same</span>
<a name="208" /><span class="True">     208:</span> <span class="k"> * srcu_struct, whether directly or indirectly.  Please note that</span>
<a name="209" /><span class="True">     209:</span> <span class="k"> * one way to indirectly wait on an SRCU grace period is to acquire</span>
<a name="210" /><span class="True">     210:</span> <span class="k"> * a mutex that is held elsewhere while calling synchronize_srcu() or</span>
<a name="211" /><span class="True">     211:</span> <span class="k"> * synchronize_srcu_expedited().</span>
<a name="212" /><span class="True">     212:</span> <span class="k"> *</span>
<a name="213" /><span class="True">     213:</span> <span class="k"> * Note that srcu_read_lock() and the matching srcu_read_unlock() must</span>
<a name="214" /><span class="True">     214:</span> <span class="k"> * occur in the same context, for example, it is illegal to invoke</span>
<a name="215" /><span class="True">     215:</span> <span class="k"> * srcu_read_unlock() in an irq handler if the matching srcu_read_lock()</span>
<a name="216" /><span class="True">     216:</span> <span class="k"> * was invoked in process context.</span>
<a name="217" /><span class="True">     217:</span> <span class="k"> */</span>
<a name="218" /><span class="True">     218:</span> <span class="m">static</span> <span class="m">inline</span> <span class="m">int</span> <span class="b">srcu_read_lock</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">)</span> <a href="cpu.c_macros_ref.html#_X19hY3F1aXJlc18w"><span class="b">__acquires</span></a><span class="f">(</span><span class="b">sp</span><span class="f">)</span>
<a name="219" /><span class="True">     219:</span> <span class="f">{</span>
<a name="220" /><span class="True">     220:</span>     <span class="m">int</span> <span class="b">retval</span> <span class="f">=</span> <span class="b">__srcu_read_lock</span><span class="f">(</span><span class="b">sp</span><span class="f">)</span><span class="f">;</span>
<a name="221" /><span class="True">     221:</span> 
<a name="222" /><span class="True">     222:</span>     <a href="cpu.c_macros_ref.html#_cmN1X2xvY2tfYWNxdWlyZV8w"><span class="b">rcu_lock_acquire</span></a><span class="f">(</span><span class="f">&amp;</span><span class="f">(</span><span class="b">sp</span><span class="f">)</span><span class="f">-&gt;</span><span class="b">dep_map</span><span class="f">)</span><span class="f">;</span>
<a name="223" /><span class="True">     223:</span>     <span class="m">return</span> <span class="b">retval</span><span class="f">;</span>
<a name="224" /><span class="True">     224:</span> <span class="f">}</span>
<a name="225" /><span class="True">     225:</span> 
<a name="226" /><span class="True">     226:</span> <span class="k">/**</span>
<a name="227" /><span class="True">     227:</span> <span class="k"> * srcu_read_unlock - unregister a old reader from an SRCU-protected structure.</span>
<a name="228" /><span class="True">     228:</span> <span class="k"> * @sp: srcu_struct in which to unregister the old reader.</span>
<a name="229" /><span class="True">     229:</span> <span class="k"> * @idx: return value from corresponding srcu_read_lock().</span>
<a name="230" /><span class="True">     230:</span> <span class="k"> *</span>
<a name="231" /><span class="True">     231:</span> <span class="k"> * Exit an SRCU read-side critical section.</span>
<a name="232" /><span class="True">     232:</span> <span class="k"> */</span>
<a name="233" /><span class="True">     233:</span> <span class="m">static</span> <span class="m">inline</span> <span class="m">void</span> <span class="b">srcu_read_unlock</span><span class="f">(</span><span class="m">struct</span> <span class="b">srcu_struct</span> <span class="f">*</span><span class="b">sp</span><span class="f">,</span> <span class="m">int</span> <span class="b">idx</span><span class="f">)</span>
<a name="234" /><span class="True">     234:</span>     <a href="cpu.c_macros_ref.html#_X19yZWxlYXNlc18w"><span class="b">__releases</span></a><span class="f">(</span><span class="b">sp</span><span class="f">)</span>
<a name="235" /><span class="True">     235:</span> <span class="f">{</span>
<a name="236" /><span class="True">     236:</span>     <a href="cpu.c_macros_ref.html#_cmN1X2xvY2tfcmVsZWFzZV8w"><span class="b">rcu_lock_release</span></a><span class="f">(</span><span class="f">&amp;</span><span class="f">(</span><span class="b">sp</span><span class="f">)</span><span class="f">-&gt;</span><span class="b">dep_map</span><span class="f">)</span><span class="f">;</span>
<a name="237" /><span class="True">     237:</span>     <span class="b">__srcu_read_unlock</span><span class="f">(</span><span class="b">sp</span><span class="f">,</span> <span class="b">idx</span><span class="f">)</span><span class="f">;</span>
<a name="238" /><span class="True">     238:</span> <span class="f">}</span>
<a name="239" /><span class="True">     239:</span> 
<a name="240" /><span class="True">     240:</span> <span class="k">/**</span>
<a name="241" /><span class="True">     241:</span> <span class="k"> * smp_mb__after_srcu_read_unlock - ensure full ordering after srcu_read_unlock</span>
<a name="242" /><span class="True">     242:</span> <span class="k"> *</span>
<a name="243" /><span class="True">     243:</span> <span class="k"> * Converts the preceding srcu_read_unlock into a two-way memory barrier.</span>
<a name="244" /><span class="True">     244:</span> <span class="k"> *</span>
<a name="245" /><span class="True">     245:</span> <span class="k"> * Call this after srcu_read_unlock, to guarantee that all memory operations</span>
<a name="246" /><span class="True">     246:</span> <span class="k"> * that occur after smp_mb__after_srcu_read_unlock will appear to happen after</span>
<a name="247" /><span class="True">     247:</span> <span class="k"> * the preceding srcu_read_unlock.</span>
<a name="248" /><span class="True">     248:</span> <span class="k"> */</span>
<a name="249" /><span class="True">     249:</span> <span class="m">static</span> <span class="m">inline</span> <span class="m">void</span> <span class="b">smp_mb__after_srcu_read_unlock</span><span class="f">(</span><span class="m">void</span><span class="f">)</span>
<a name="250" /><span class="True">     250:</span> <span class="f">{</span>
<a name="251" /><span class="True">     251:</span>     <span class="k">/* __srcu_read_unlock has smp_mb() internally so nothing to do here. */</span>
<a name="252" /><span class="True">     252:</span> <span class="f">}</span>
<a name="253" /><span class="True">     253:</span> 
<a name="254" /><span class="True">     254:</span> <span class="f">#</span><span class="n">endif</span>
<a name="255" /><span class="True">     255:</span> </pre>
  </body>
</html>
